package com.huahua.api.util;


import org.dromara.hutool.http.HttpUtil;
import org.dromara.hutool.http.client.Request;
import org.dromara.hutool.http.meta.Method;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CurlUtils {

    private static final Pattern CURL_URL_PATTERN = Pattern.compile("curl\\s+(?:'([^']*)'|\"([^\"]*)\"|([^\\s]+))");
    private static final Pattern HEADER_PATTERN = Pattern.compile("-H\\s+['\"]([^'\"]+)['\"]");
    private static final Pattern METHOD_PATTERN = Pattern.compile("-X\\s+(\\w+)");
    private static final Pattern INSECURE_PATTERN = Pattern.compile("--insecure");
    private static final Pattern DATA_PATTERN_MULTILINE = Pattern.compile("(?:-d|--data|--data-raw|--data-binary)\\s+(?:'([^']*(?:\\\\'[^']*)*)'|\"([^\"]*(?:\\\\\"[^\"]*)*)\"|([^\\s]+))", Pattern.DOTALL);
    private static final Pattern FORM_PATTERN = Pattern.compile("(?:-F|--form)\\s+['\"]([^'\"]+)['\"]");
    private static final Pattern COOKIE_PATTERN = Pattern.compile("(?:-b|--cookie)\\s+['\"]([^'\"]+)['\"]");
    private static final Pattern USER_PATTERN = Pattern.compile("(?:-u|--user)\\s+['\"]([^'\"]+)['\"]");
    private static final Pattern REFERER_PATTERN = Pattern.compile("(?:-e|--referer)\\s+['\"]([^'\"]+)['\"]");
    private static final Pattern USER_AGENT_PATTERN = Pattern.compile("(?:-A|--user-agent)\\s+['\"]([^'\"]+)['\"]");

    public static String replaceDomain(String curlCommand, String newDomain) {
        if (curlCommand == null || curlCommand.trim().isEmpty()) {
            throw new IllegalArgumentException("Curl command cannot be null or empty");
        }

        if (newDomain == null || newDomain.trim().isEmpty()) {
            throw new IllegalArgumentException("New domain cannot be null or empty");
        }

        if (!curlCommand.trim().startsWith("curl")) {
            throw new IllegalArgumentException("Invalid curl command format");
        }

        Matcher curlMatcher = CURL_URL_PATTERN.matcher(curlCommand);
        if (!curlMatcher.find()) {
            throw new IllegalArgumentException("No URL found in curl command");
        }

        String originalUrl = curlMatcher.group(1) != null ? curlMatcher.group(1) :
                curlMatcher.group(2) != null ? curlMatcher.group(2) : curlMatcher.group(3);

        try {
            URL url = new URL(originalUrl);
            String newUrl = newDomain + url.getPath();
            if (url.getQuery() != null) {
                newUrl += "?" + url.getQuery();
            }
            if (url.getRef() != null) {
                newUrl += "#" + url.getRef();
            }

            return curlCommand.replace(originalUrl, newUrl);
        } catch (MalformedURLException e) {
            throw new IllegalArgumentException("Invalid URL format in curl command: " + originalUrl);
        }
    }

    public static boolean isValidCurlCommand(String curlCommand) {
        if (curlCommand == null || curlCommand.trim().isEmpty()) {
            return false;
        }

        if (!curlCommand.trim().startsWith("curl")) {
            return false;
        }

        Matcher matcher = CURL_URL_PATTERN.matcher(curlCommand);
        if (!matcher.find()) {
            return false;
        }

        String url = matcher.group(1) != null ? matcher.group(1) :
                matcher.group(2) != null ? matcher.group(2) : matcher.group(3);
        try {
            new URL(url);
            return true;
        } catch (MalformedURLException e) {
            return false;
        }
    }

    public static String extractDomain(String curlCommand) {
        if (!isValidCurlCommand(curlCommand)) {
            throw new IllegalArgumentException("Invalid curl command");
        }

        Matcher curlMatcher = CURL_URL_PATTERN.matcher(curlCommand);
        if (curlMatcher.find()) {
            String url = curlMatcher.group(1) != null ? curlMatcher.group(1) :
                    curlMatcher.group(2) != null ? curlMatcher.group(2) : curlMatcher.group(3);
            try {
                URL urlObj = new URL(url);
                return urlObj.getProtocol() + "://" + urlObj.getHost() + (urlObj.getPort() != -1 ? ":" + urlObj.getPort() : "");
            } catch (MalformedURLException e) {
                throw new IllegalArgumentException("Invalid URL format: " + url);
            }
        }

        throw new IllegalArgumentException("No URL found in curl command");
    }

    public static String executeCurl(String curlCommand) {
        return executeCurl(curlCommand, 30000);
    }

    public static String executeCurl(String curlCommand, int timeoutMs) {
        if (!isValidCurlCommand(curlCommand)) {
            throw new IllegalArgumentException("Invalid curl command");
        }

        try {
            String url = extractUrl(curlCommand);
            Method method = extractMethod(curlCommand);
            Map<String, String> headers = extractHeaders(curlCommand);
            String data = extractData(curlCommand);
            String formData = extractFormData(curlCommand);
            String basicAuth = extractBasicAuth(curlCommand);
            boolean insecure = extractInsecure(curlCommand);

            addStandardHeaders(curlCommand, headers);

            if (basicAuth != null) {
                String[] auth = basicAuth.split(":", 2);
                if (auth.length == 2) {
                    String credentials = java.util.Base64.getEncoder().encodeToString((auth[0] + ":" + auth[1]).getBytes());
                    headers.put("Authorization", "Basic " + credentials);
                }
            }



            String response;
            Request request = HttpUtil.createRequest(url, method);

            // Set headers
            if (headers != null && !headers.isEmpty()) {
                request.header(headers);
            }

            // Set timeout
//            request.(timeoutMs);

            // Set method and body
            switch (method) {
                case GET:
                    break;
                case POST:
                    String postData = data != null ? data : (formData != null ? formData : "");
                    request.body(postData);
                    break;
                case PUT:
                    String putData = data != null ? data : (formData != null ? formData : "");
                    request.body(putData);
                    break;
                case DELETE:
                    break;
                default:
                    String requestData = data != null ? data : (formData != null ? formData : "");
                    request.body(requestData);
                    break;
            }

            // Execute request and get response
            response = request.send().bodyStr();

            return response;
        } catch (Exception e) {
            throw new RuntimeException("Failed to execute curl command: " + e.getMessage(), e);
        }
    }

    private static String extractUrl(String curlCommand) {
        Matcher matcher = CURL_URL_PATTERN.matcher(curlCommand);
        if (matcher.find()) {
            if (matcher.group(1) != null) {
                return matcher.group(1);
            } else if (matcher.group(2) != null) {
                return matcher.group(2);
            } else if (matcher.group(3) != null) {
                return matcher.group(3);
            }
        }
        throw new IllegalArgumentException("No URL found in curl command");
    }

    private static Method extractMethod(String curlCommand) {
        Matcher matcher = METHOD_PATTERN.matcher(curlCommand);
        if (matcher.find()) {
            String methodStr = matcher.group(1).toUpperCase();
            try {
                return Method.valueOf(methodStr);
            } catch (IllegalArgumentException e) {
                return Method.GET;
            }
        }

        if (DATA_PATTERN_MULTILINE.matcher(curlCommand).find() ||
                FORM_PATTERN.matcher(curlCommand).find()) {
            return Method.POST;
        }

        return Method.GET;
    }

    private static Map<String, String> extractHeaders(String curlCommand) {
        Map<String, String> headers = new HashMap<>();
        Matcher matcher = HEADER_PATTERN.matcher(curlCommand);
        while (matcher.find()) {
            String header = matcher.group(1);
            String[] parts = header.split(":", 2);
            if (parts.length == 2) {
                headers.put(parts[0].trim(), parts[1].trim());
            }
        }
        return headers;
    }

    private static String extractData(String curlCommand) {
        Matcher matcher = DATA_PATTERN_MULTILINE.matcher(curlCommand);
        if (matcher.find()) {
            if (matcher.group(1) != null) {
                return matcher.group(1).replace("\\'", "'");
            } else if (matcher.group(2) != null) {
                return matcher.group(2).replace("\\\"", "\"");
            } else if (matcher.group(3) != null) {
                return matcher.group(3);
            }
        }
        return null;
    }

    private static boolean extractInsecure(String curlCommand) {
        return INSECURE_PATTERN.matcher(curlCommand).find();
    }

    private static void addStandardHeaders(String curlCommand, Map<String, String> headers) {
        Matcher userAgentMatcher = USER_AGENT_PATTERN.matcher(curlCommand);
        if (userAgentMatcher.find() && !headers.containsKey("User-Agent")) {
            headers.put("User-Agent", userAgentMatcher.group(1));
        }

        Matcher refererMatcher = REFERER_PATTERN.matcher(curlCommand);
        if (refererMatcher.find() && !headers.containsKey("Referer")) {
            headers.put("Referer", refererMatcher.group(1));
        }

        Matcher cookieMatcher = COOKIE_PATTERN.matcher(curlCommand);
        if (cookieMatcher.find() && !headers.containsKey("Cookie")) {
            headers.put("Cookie", cookieMatcher.group(1));
        }
    }

    private static String extractFormData(String curlCommand) {
        StringBuilder formData = new StringBuilder();
        Matcher matcher = FORM_PATTERN.matcher(curlCommand);
        while (matcher.find()) {
            if (formData.length() > 0) {
                formData.append("&");
            }
            formData.append(matcher.group(1));
        }
        return formData.length() > 0 ? formData.toString() : null;
    }

    private static String extractBasicAuth(String curlCommand) {
        Matcher matcher = USER_PATTERN.matcher(curlCommand);
        if (matcher.find()) {
            return matcher.group(1);
        }
        return null;
    }

}
